package cn.anzhiyublog.staranimegallery.aop;

import cn.anzhiyublog.staranimegallery.annotation.Auth;
import cn.anzhiyublog.staranimegallery.annotation.Role;
import cn.anzhiyublog.staranimegallery.exception.GalleryException;
import cn.anzhiyublog.staranimegallery.model.enums.Authority;
import cn.anzhiyublog.staranimegallery.model.enums.StatusCode;
import cn.anzhiyublog.staranimegallery.service.UserService;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;

/**
 * 权限校验AOP
 *
 * @author 安知一只鱼
 */
@Aspect
@Component
public class AuthInterceptor {
    @Autowired
    private UserService userService;

    /**
     * 监听@role注解，进行角色校验
     */
    @Around("@annotation(role)")
    public Object doInterceptor(ProceedingJoinPoint proceedingJoinPoint, Role role) throws Throwable {
        // 获取传入的数据，可以放行的角色数组
        cn.anzhiyublog.staranimegallery.model.enums.Role[] roles = role.value();
        // 获取登录角色
        Integer loginRoleCode = this.getLoginRoleCode();
        // 遍历循环比对
        for (cn.anzhiyublog.staranimegallery.model.enums.Role r : roles){
            if (r.getCode().equals(loginRoleCode)){
                // 如果有该角色则放行
                return proceedingJoinPoint.proceed();
            }
        }
        // 没有则抛无权限异常
        throw new GalleryException(StatusCode.FORBIDDEN,"您无权这么做");
    }

    /**
     * 监听@auth注解，进行权限组校验
     */
    @Around("@annotation(auth)")
    public Object doInterceptor(ProceedingJoinPoint proceedingJoinPoint, Auth auth) throws Throwable {
        // 获取传入的数据，可以放行的权限组
        Authority[] authorities = auth.value();
        // 获取登录角色
        Integer loginRoleCode = this.getLoginRoleCode();
        cn.anzhiyublog.staranimegallery.model.enums.Role role =
                cn.anzhiyublog.staranimegallery.model.enums.Role.getEnumByCode(loginRoleCode);
        // 遍历循环比对
        for (Authority authority : authorities){
            if (role==null)
                break;
            int[] range = authority.getRange();
            if (role.getCode()>=range[0]&&role.getCode()<=range[1]){
                // 如果有该角色则放行
                return proceedingJoinPoint.proceed();
            }
        }
        // 没有则抛无权限异常
        throw new GalleryException(StatusCode.FORBIDDEN);
    }

    /**
     * 获取当前登录的角色
     */
    private Integer getLoginRoleCode(){
        // 获取当前请求体所有字段
        RequestAttributes requestAttributes = RequestContextHolder.currentRequestAttributes();
        ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes) requestAttributes;
        // 获取当前登录的session
        HttpServletRequest request = servletRequestAttributes.getRequest();
        // 获取登录用户角色
        return userService.getLoginUser(request).getRole();
    }
}
